package cn.sccl.dirms.topo.discovery.controller;

import cn.sccl.common.exception.scheduler.TaskIsExitingException;
import cn.sccl.common.model.PageResult;
import cn.sccl.common.scheduler.SchedulerService;
import cn.sccl.common.scheduler.enums.JobTypeEnum;
import cn.sccl.common.scheduler.enums.TaskTypeEnum;
import cn.sccl.common.scheduler.model.TaskFireLog;
import cn.sccl.common.scheduler.model.TaskScheduled;
import cn.sccl.common.web.BaseController;
import cn.sccl.dirms.topo.discovery.model.DiscoverTask;
import cn.sccl.dirms.topo.discovery.model.DiscoverTaskSchedule;
import cn.sccl.dirms.topo.discovery.model.DiscoverTaskVO;
import cn.sccl.dirms.topo.discovery.service.DiscoverTaskManager;
import cn.sccl.dirms.topo.discovery.service.DiscoverTaskScheduleManager;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* 自动发现任务表 的Controller
* Created by _minus on 2017-09-26.
*/
@RestController
@RequestMapping(value = "/nms/topo/discovery/discoverTask")
public class DiscoverTaskController extends BaseController {

    @Autowired
    private DiscoverTaskManager discoverTaskManager;

    @Autowired
    private SchedulerService schedulerService ;

    @Autowired
    private DiscoverTaskScheduleManager discoverTaskScheduleManager;

    /**
    * 显示所有数据
    */
    @RequestMapping(value = "/all" , method = RequestMethod.GET)
    public List<DiscoverTask> listAllDiscoverTask(){
        return discoverTaskManager.listAll();
    }

    /**
    * 分页查询，分页参数放置在url路径中
    * @param pageIndex 页码
    * @param pageSize 分页大小
    * @param request
    * @return
    */
    @RequestMapping(value = "/page/{pageIndex}/{pageSize}" , method = RequestMethod.GET)
    public PageResult<DiscoverTask> pageQueryDiscoverTask(@PathVariable("pageIndex") long pageIndex , @PathVariable("pageSize") int pageSize , HttpServletRequest request){
        return discoverTaskManager.pageQueryByLike(pageIndex, pageSize, getQueryData(request));
    }

    /**
    * 分页查询，分页参数放置在request中
    * @param request
    * @return
    */
    @Deprecated
    @RequestMapping(value = "/page" , method = RequestMethod.GET )
    public PageResult<DiscoverTask> pageQueryDiscoverTask(HttpServletRequest request){
        return discoverTaskManager.pageQueryByLike(getPageIndex(request), getPageSize(request), getQueryData(request));
    }


    /**
     * 新建或者修改 自动发现任务
     * @param discoverTaskVO
     * @return
     */
    @RequestMapping(value = "/save/" , method = RequestMethod.POST)
    public DiscoverTaskVO saveDiscoverTaskVO(@RequestBody DiscoverTaskVO discoverTaskVO){
        DiscoverTask discoverTask = new DiscoverTask();

        DiscoverTaskSchedule discoverTaskSchedule = new DiscoverTaskSchedule();
        String jsonStr = JSON.toJSON(discoverTaskVO).toString() ;

        discoverTask  = JSON.parseObject(jsonStr,DiscoverTask.class);

        discoverTaskSchedule  = JSON.parseObject(jsonStr,DiscoverTaskSchedule.class);

        boolean isNewTask = StringUtils.isEmpty(discoverTaskVO.getTaskId());
        boolean isNewSchedule = StringUtils.isEmpty(discoverTaskVO.getTaskScheduleId());

        if (!isNewTask){
            discoverTask.setId(discoverTaskVO.getTaskId());
        }else{
            //检查name ，和groupName 是否已经重复
            TaskScheduled taskScheduled = new TaskScheduled();
            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());
            if (schedulerService.isExist(taskScheduled)){
                //抛出异常
                throw new TaskIsExitingException();
            }
        }
        if (!isNewSchedule){
            discoverTaskSchedule.setId(discoverTaskVO.getTaskScheduleId());
        }

        //先保存task
        discoverTask.setName(discoverTaskVO.getName());
        discoverTaskManager.save(discoverTask);

        String taskId = discoverTask.getId() ;
        discoverTaskSchedule.setTaskId(taskId);
        
        discoverTaskScheduleManager.save(discoverTaskSchedule);
//        组装 TaskScheduled
        TaskScheduled taskScheduled = initTaskScheduledByDiscoverTaskAndSchedule(discoverTask,discoverTaskSchedule);

        schedulerService.updateTask(taskScheduled);

        if("0".equals(discoverTask.getActive())){
            //如果是不启用
            schedulerService.pauseJob(taskScheduled);
        }
        discoverTaskVO.setTaskId(taskId);
        discoverTaskVO.setTaskScheduleId(discoverTaskSchedule.getId());
        return discoverTaskVO ;

    }


    /**
     * 传递归来的是t_topo_discover_task 表中的 id ,
     * 先根据id 查出 DiscoverTask,再判断是否有job存在，再将属性写入VO中
     * @param id
     * @return
     */
    @RequestMapping(value = "/find/{id}" , method = RequestMethod.GET)
    public DiscoverTaskVO queryDiscoverTaskVOById(@PathVariable("id") String id){
        DiscoverTaskVO discoverTaskVO = new DiscoverTaskVO();
        if(!StringUtils.isEmpty(id)){
            DiscoverTask discoverTask = discoverTaskManager.get(id);
            if (discoverTask != null) {
                TaskScheduled taskScheduled = new TaskScheduled();
                taskScheduled.setTaskName(discoverTask.getName());
                taskScheduled.setTaskGroup(discoverTask.getGroupName());
                if (schedulerService.isExist(taskScheduled)){
                    discoverTaskVO = discoverTaskManager.queryDiscoverTaskVoByTaskId(id);
                }
            }
        }
        return discoverTaskVO ;

    }




        /**
         * 这才是 quartz 中所需要用到的task 的属性，
         *
         * @param discoverTask
         * @param discoverTaskSchedule
         * @return
         */
    private TaskScheduled initTaskScheduledByDiscoverTaskAndSchedule(DiscoverTask discoverTask, DiscoverTaskSchedule discoverTaskSchedule) {

        TaskScheduled taskScheduled = new TaskScheduled();

        taskScheduled.setTaskName(discoverTask.getName());
        taskScheduled.setTaskGroup(discoverTask.getGroupName());
        taskScheduled.setTargetObject(discoverTask.getTargetObject());
        taskScheduled.setTargetMethod(discoverTask.getTargetMethod());
        //这里将discover_task 的id 作为参数传递到targetMethod中
        taskScheduled.setTargetParams(discoverTask);


        taskScheduled.setTaskDesc(discoverTask.getName()); //将任务名作为任务描述


        taskScheduled.setStartTime(discoverTaskSchedule.getStartTime());
        taskScheduled.setEndTime(discoverTaskSchedule.getEndTime());

        taskScheduled.setTaskCron(discoverTaskSchedule.getCron());

        //非阻塞任务
        taskScheduled.setJobType(JobTypeEnum.STATEFUL_JOB.getType());

        //这是自动发现任务 类型 ,由前台传递
        taskScheduled.setTaskType(TaskTypeEnum.DISCOVER_TASK.getType());



        return taskScheduled ;
    }



    /**
        * 保存数据
        * @param discoverTask
        * @return
        */
    @Deprecated
    @RequestMapping(value = "/" , method = RequestMethod.POST)
    public DiscoverTask saveDiscoverTask(@RequestBody DiscoverTask discoverTask){
        boolean isNew = StringUtils.isEmpty(discoverTask.getId()) ;
        if (isNew){
            //判断任务名，任务群组是否重复
            TaskScheduled taskScheduled = new TaskScheduled() ;
            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());

            if (schedulerService.isExist(taskScheduled)){
                //抛出任务名重复异常
            }else {
                //新建自动任务

            }

        }
//        discoverTaskManager.save(discoverTask);
        return discoverTask;
    }


    // TODO: 2017/9/27 根据graphy id 查询该topo 下的自动发现任务

    @RequestMapping(value = "/graphy/{id}" , method = RequestMethod.GET)
    public List<DiscoverTaskVO> queryDiscoverTasksByGraphyId(@PathVariable("id") String id){

        //这里从quartz 中获取到所有的 任务作业
        List<TaskScheduled> taskScheduleds = schedulerService.getAllTaskDetail();

        List<DiscoverTaskVO>  discoverTasks = discoverTaskManager.queryDiscoverTaskVoByGraphyId(id);
        // discoverTasks taskName，taskGroup与 taskScheduleds  name,groupName对应匹配
        //这里之所以这么做，是 我还没弄懂，quartz 表，如何通过sql 查询出task，暂时这么做，以后优化-。-

        List<DiscoverTaskVO> result = new ArrayList<DiscoverTaskVO>() ;
        for (TaskScheduled taskScheduled : taskScheduleds) {

            for (DiscoverTaskVO discoverTask : discoverTasks) {

                if (taskScheduled.getTaskName().equals(discoverTask.getName()) && taskScheduled.getTaskGroup().equals(discoverTask.getGroupName())){
                    discoverTask = this.initDiscoverTaskVoFromTaskScheduled(discoverTask,taskScheduled);
                    result.add(discoverTask);
                }
            }
        }
//        Collections.sort(result);
        return result ;


    }

    /**
     * 将  TaskScheduled  写入到  DiscoverTaskVo
     * @param discoverTaskVo
     * @param taskScheduled
     * @return
     */
    private DiscoverTaskVO initDiscoverTaskVoFromTaskScheduled(DiscoverTaskVO discoverTaskVo, TaskScheduled taskScheduled) {
        discoverTaskVo.setStatus(taskScheduled.getStatus());
        Date perTime = taskScheduled.getPreviousFireTime() ;
        Date nextTime = taskScheduled.getNextFireTime() ;
        if (perTime!=null){
            discoverTaskVo.setPreviousFireTime(new Timestamp(perTime.getTime()));
        }
        if (nextTime!=null){
            discoverTaskVo.setNextFireTime(new Timestamp(nextTime.getTime()));
        }
        return discoverTaskVo ;
    }


    @RequestMapping(value = "/graphy/page/{id}" , method = RequestMethod.GET)
    public PageResult<DiscoverTask> pageQueryDiscoverTasksByGraphyId(@PathVariable("id") String id , HttpServletRequest request){
        return discoverTaskManager.pageQueryDiscoverTasksByGraphyId(id,getPageIndex(request),getPageSize(request),getQueryData(request));
    }


    /**
     * 根据taskid 分页 查询 T_TASK_FIRE_LOG 中该任务的日志
     * @param taskId
     * @param request
     * @return
     */
    @RequestMapping(value = "/task/{taskId}/fire/logs",method = RequestMethod.GET)
    public PageResult<TaskFireLog> pageQueryTaskFireLogsByTaskId(@PathVariable("taskId") String taskId, HttpServletRequest request) {
        return discoverTaskManager.pageQueryTaskFireLogsByTaskId(taskId,getPageIndex(request),getPageSize(request),getQueryData(request));
    }

    /**
    * 根据ID删除数据
    * @param id
    */
    @RequestMapping(value = "/{id}" , method = RequestMethod.DELETE)
    @JsonView(Object.class)
    public void deleteDiscoverTask(@PathVariable("id") String id){
        //删除task 需要删除关系，删除job
        DiscoverTask discoverTask =discoverTaskManager.get(id) ;

        if (discoverTask!=null){
            discoverTaskManager.delete(id);
            TaskScheduled taskScheduled = new TaskScheduled();

            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());

            if (schedulerService.isExist(taskScheduled)){
                schedulerService.delTask(taskScheduled);
            }

        }
    }


    /**
     * 任务暂停
     * @param id
     * @return
     */
    @RequestMapping(value = "/pauseJob/{id}" ,method = RequestMethod.GET)
    public DiscoverTaskVO  pauseJob(@PathVariable("id") String id){

        DiscoverTask discoverTask = discoverTaskManager.get(id);
        DiscoverTaskVO discoverTaskVO =discoverTaskManager.queryDiscoverTaskVoByTaskId(id);
        if (discoverTask!=null){
            TaskScheduled taskScheduled = new TaskScheduled();
            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());

            schedulerService.pauseJob(taskScheduled);

            taskScheduled = schedulerService.getJobDetail(taskScheduled);
            discoverTaskVO =this.initDiscoverTaskVoFromTaskScheduled(discoverTaskVO,taskScheduled);
        }
        return discoverTaskVO ;
    }

    //    任务恢复

    /**
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/resumeJob/{id}" ,method = RequestMethod.GET)
    public DiscoverTaskVO  resumeJob(@PathVariable("id") String id){

        DiscoverTask discoverTask = discoverTaskManager.get(id);
        DiscoverTaskVO discoverTaskVO =discoverTaskManager.queryDiscoverTaskVoByTaskId(id);
        if (discoverTask!=null){
            TaskScheduled taskScheduled = new TaskScheduled();
            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());
            schedulerService.resumeJob(taskScheduled);

            taskScheduled = schedulerService.getJobDetail(taskScheduled);

            discoverTaskVO =this.initDiscoverTaskVoFromTaskScheduled(discoverTaskVO,taskScheduled);
        }

        return discoverTaskVO ;
    }

    //任务 立即执行


    @RequestMapping(value = "/execJob/{id}" ,method = RequestMethod.GET)
    public DiscoverTaskVO  execJob(@PathVariable("id") String id){
        DiscoverTask discoverTask = discoverTaskManager.get(id);
        DiscoverTaskVO discoverTaskVO =discoverTaskManager.queryDiscoverTaskVoByTaskId(id);
        if (discoverTask!=null){
            TaskScheduled taskScheduled = new TaskScheduled();
            taskScheduled.setTaskName(discoverTask.getName());
            taskScheduled.setTaskGroup(discoverTask.getGroupName());
            schedulerService.execTask(taskScheduled);
            taskScheduled = schedulerService.getJobDetail(taskScheduled);
            discoverTaskVO =this.initDiscoverTaskVoFromTaskScheduled(discoverTaskVO,taskScheduled);
        }

        return discoverTaskVO ;
    }

}
